<!DOCTYPE html>
<html lang="zh-CN">

<head>
  <meta charset="utf-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <title>在线聊天</title>

  <style>
    /*滚动条*/
    ::-webkit-scrollbar {
      /*滚动条整体样式*/
      width: 5px;
      /*高宽分别对应横竖滚动条的尺寸*/
      height: 1px;
    }

    ::-webkit-scrollbar-thumb {
      /*滚动条里面小方块*/
      border-radius: 5px;
      -webkit-box-shadow: inset 0 0 5px rgba(0, 0, 0, 0.2);
      background: #333;
    }

    ::-webkit-scrollbar-track {
      /*滚动条里面轨道*/
      -webkit-box-shadow: inset 0 0 5px rgba(0, 0, 0, 0.2);
      border-radius: 10px;
      background: transparent;
    }

    @media screen and (min-width: 600px) {
      .react.container {
        width: 320px;
        height: 90vh;
        margin-top: 5vh;
        margin-left: 50%;
        transform: translateX(-50%);
        border: 1px solid #eee;
        border-radius: 5px;
        box-shadow: 0 2px 8px 0 rgba(0, 0, 0, 0.15);
        font-size: 14px;
      }
    }

    html,
    body,
    #app {
      height: 100%;
      margin: 0;
      overflow: hidden;
      background: lightslategrey;
      font-size: 16px;
    }

    .container {
      margin: 0;
      display: flex;
      flex-direction: column;
      height: 100%;
    }

    .chat-list {
      flex: 1;
      margin-top: 20px;
      overflow-y: auto;
    }

    .chat-list .msg-wrap {
      display: flex;
      color: #FFF;
    }

    .msg-wrap .nickname {
      display: flex;
      align-items: flex-end;
      font-size: 12px;
      color: #CCC;
      margin-bottom: 10px;
      margin-left: -10px;
    }

    .msg-wrap.sent .nickname {
      margin-right: -10px;
      margin-bottom: -10px;
    }

    .msg-wrap.sent {
      flex-direction: row-reverse;
      align-items: center;
    }

    .msg-wrap.sent .msg-item {
      background: #1a73e8;
    }

    /* 发送中 */
    .msg-wrap.sent.sending {
      color: #CCC;
    }

    .chat-list .msg-item {
      display: inline-block;
      padding: 10px 15px;
      border: 1px solid #eee;
      border-radius: 5px;
      box-shadow: 0 2px 8px 0 rgba(0, 0, 0, 0.15);
      margin: 10px 20px;
      display: flex;
      max-width: 70%;
      word-wrap: break-word;
    }

    .word-wrap {
      width: 100%;
      word-wrap: break-word;
    }

    .input-box {}

    .input-box .msg-input {
      background: none;
      border: none;
      border: 1px solid #eee;
      box-shadow: 0 2px 8px 0 rgba(0, 0, 0, 0.15);
      padding: 10px;
      border-radius: 15px;
      width: calc(100% - 40px);
      margin: 10px;
      outline: none;
      color: #FFF;
    }

    .msg-input::placeholder {
      color: #DDD;
      opacity: 1;
    }

    .header {
      height: 50px;
      border-bottom: 1px solid #CCC;
      display: flex;
      justify-content: space-between;
      align-items: center;
      padding: 0 15px;
      color: #EEE;
    }

    .btn {
      cursor: pointer;
      margin-left: 5px;
    }

    .btn:hover {
      color: #FFF;
    }

    .hidden {
      display: none !important;
    }

    .form-row {
      display: flex;
      align-items: center;
      margin-bottom: 20px;
    }

    .form-row .label {
      width: 90px;
      color: #666;
      text-align: right;
    }

    .form-row .field {
      flex: 1;
      text-align: left;
      margin-left: 20px;
      line-height: 1.5em;
    }

    .form-row .field input {
      display: inline-block;
      width: 200px;
    }

    .form-row .check {
      cursor: pointer;
      font-size: 18px;
      font-weight: bold;
      margin-right: 8px;
    }

    .form-row .check.check-yes {
      color: green;
    }

    .form-row .check.check-no {
      color: red;
    }

    .swal-modal {
      width: 90%;
      max-width: 550px;
    }
  </style>
</head>

<body>
  <div id="app">
    <audio style="display: none;" id="dingdong" src="./sound/dingdong.mp3"></audio>
    <div class="container react">
      <div class="header">
        <span>在线聊天 - <span v-text="title"></span></span>
        <div>
          <!-- <span @click="handleSetting" class="btn">设置</span> -->
        </div>
      </div>
      <div class="chat-list">
        <template v-if="item.content" v-for="item in list">
          <div v-if="item.user == user" class="msg-wrap sent" :class="{sending:item.state=='sending'}">
            <div class="msg-item">
              <span class="word-wrap" v-text="item.content"></span>
            </div>
            <div class="nickname" v-text="item.nickname"></div>
          </div>
          <div v-else class="msg-wrap recv">
            <div class="msg-item">
              <span class="word-wrap" v-text="item.content"></span>
            </div>
            <div class="nickname" v-text="item.nickname"></div>
          </div>
        </template>

      </div>
      <div class="input-box">
        <input v-model="input" @keyup.enter="handleSendMsg()" class="msg-input" type="text" placeholder="Enter发送">
      </div>
    </div>


    <div :class="{hidden:!settingDailog}" class="swal-overlay swal-overlay--show-modal" tabindex="-1">
      <div class="swal-modal" role="dialog" aria-modal="true">
        <div style="height: 20px;"></div>
        <div class="swal-content">
          <div class="form-row">
            <span class="label">设置昵称:</span>
            <div class="field">
              <input v-model="data.nickname" class="swal-content__input" placeholder="">
            </div>
          </div>

          <div class="form-row">
            <span class="label">房间号:</span>
            <div class="field">
              <input v-model="data.roomNo" class="swal-content__input" placeholder="">
            </div>
          </div>

          <div class="form-row">
            <span class="label">房间密码:</span>
            <div class="field">
              <input v-model="data.roomPwd" type="password" class="swal-content__input" placeholder="">
            </div>
          </div>

          <div class="form-row">
            <span class="label">多人对话:</span>
            <div class="field">
              <i @click="data.groupChat = 0" v-if="data.groupChat" class="check check-yes">√</i>
              <i @click="data.groupChat = 1" v-if="!data.groupChat" class="check check-no">×</i>
            </div>
          </div>

          <div class="form-row">
            <span class="label">声音提示:</span>
            <div class="field">
              <i @click="setting.playAudio = false" v-if="setting.playAudio" class="check check-yes">√</i>
              <i @click="setting.playAudio = true" v-if="!setting.playAudio" class="check check-no">×</i>
            </div>
          </div>

          <!-- <div class="form-row">
            <div class="label">邀请:</div>
            <div class="field" style="font-size: 12px;">
              分享链接邀请对话: <br>
              <a :href="`${baseUrl}/?room=${room}`">{{baseUrl}}/?room={{room}}</a>
            </div>
          </div>

          <div class="form-row">
            <div class="label"></div>
            <div class="field" style="font-size: 12px; color: #666;">
              注: 此链接是进入此房间的唯一凭证, 此窗口关闭后数据将全部销毁.
            </div>
          </div> -->

          <div class="swal-footer">
            <div class="swal-button-container">

              <button class="swal-button swal-button--confirm" @click="handleCreateSocket('create')">创建房间</button>

              <button style="margin-left: 10px;" class="swal-button swal-button--cancel"
                @click="handleCreateSocket('join')">加入房间</button>
            </div>
          </div>
        </div>
      </div>

    </div>

</body>

<script src="./js/vue.min.js"></script>
<script src="./js/socket.io.js"></script>
<script src="./js/sweetalert.min.js"></script>

<script>
  var socket
  var app = new Vue({
    el: '#app',
    data() {
      return {
        title: '等待用户',
        master: false, //群主
        settingDailog: false,
        baseUrl: 'https://im.libiao.org',

        data: {
          nickname: '',//昵称
          roomNo: '',//房间号
          roomPwd: '',//房间密码
          groupChat: 0,
        },

        setting: {
          playAudio: false, //是否播放提示音
        },

        input: '',
        room: 'test',
        user: '',

        list: [{
          user: '',
          nickname: '',
          content: '',
          state: '',
        }],
      }
    },
    methods: {
      handleCreateSocket(action) {
        socket = io(`/?action=${action}&nickname=${this.data.nickname}&roomNo=${this.data.roomNo}&roomPwd=${this.data.roomPwd}&groupChat=${this.data.groupChat}`, {
          path: '/im'
        })
        socket.on('error', (err) => {
          if(typeof err == 'string'){
            err = JSON.parse(err)
            console.log(err)

            alert(err.msg || '未知错误')
          }else{
            console.log('error', err)

            alert(err.msg)
          }
        })
        socket.on('connect', () => {
          app.user = socket.id

          this.settingDailog = false

          if(action == 'join') app.title = `正在对话`
        })
        socket.on('msg', (data) => {
          console.log('recv', data)
          if (data.user != app.user) { //别人的消息
            app.list.push(data)

            app.title = `正在对话`

            if (app.setting.playAudio) {
              document.querySelector('#dingdong').play()
            }
            return
          }
          //设置状态
          for (let i = app.list.length - 1; i >= 0; i--) {
            let item = app.list[i]
            if (item.id == data.id) {
              item.state = 'sent' //已发送
              break;
            }
          }

          this.scroll2bottom()
        })
      },
      handleSendMsg() {
        let input = this.input
        this.input = ''

        let data = {
          user: this.user,
          room: this.data.roomNo,
          content: input,
          id: Date.now() + '' + Math.random(),
          state: 'sending', //发送中
        }

        socket.emit('msg', data)
        this.list.push(data)

        this.scroll2bottom()
      },
      handleSetting() {
        this.settingDailog = true
      },
      scroll2bottom() {
        Vue.nextTick(() => {
          let node = document.querySelector('.chat-list')
          node.scrollTop = node.scrollHeight
        })
      },
    },
    mounted() {
      this.handleSetting()

      // let room = getParameterByName('room')
      // if (!room) { //群主
      //   this.master = true
      //   room = getRandomName(8)
      // } else {
      //   this.title = `等待消息`
      // }
      // this.room = room


    },
  })

  function getParameterByName(name, url) {
    if (!url) url = window.location.href;
    name = name.replace(/[\[\]]/g, '\\$&');
    var regex = new RegExp('[?&]' + name + '(=([^&#]*)|&|#|$)'),
      results = regex.exec(url);
    if (!results) return null;
    if (!results[2]) return '';
    return decodeURIComponent(results[2].replace(/\+/g, ' '));
  }

  function getRandomName(len) {
    len = len || 2
    let str = ''
    while (len-- > 0) str += String.fromCharCode(parseInt(Math.random() * 26) + 65)
    return str
  }
</script>

</html>